
/*
 *
 */

var img = 'tiles/64/'; // 'http://tangled-gadget.googlecode.com/svn/trunk/tiles/64/';
function TangledTile(grid, row, col) {
	this.init = function() {
		this.grid = grid;
		this.row = row;
		this.col = col;
		this.t = {l: false, t: false, r: false, b: false};
		this.p = {l: 'r', t: 'b', r: 'l', b: 't'};
		this.set_type_lrtb();
		this.set_type();
	}

	this.find_tile = function(dir) {
		var r = this.row;
		var c = this.col;
		if ('l' == dir) {
			--c;
		} else if ('t' == dir) {
			--r;
		} else if ('r' == dir) {
			++c;
		} else if ('b' == dir) {
			++r;
		}
		var tile = this.grid.find_tile(r, c, true);
		if (null == tile) { 
			alert ("no tile for " + r + "," + c); 
			return this;
		}
		return tile;
	}

	this.untrace_all = function() {
		this.trace('l', false);
		this.trace('t', false);
		this.trace('r', false);
		this.trace('b', false);
	}

	this.change_type = function() {
		var t = this.get_type();
		while (this.get_type() == t) {
			this.set_type();
		}
	}

	this.set_type = function(t) {
		this.untrace_all();
		if ('ltrb' == t) {
			this.set_type_ltrb();
		} else if ('lrtb' == t) {
			this.set_type_lrtb();
		} else if ('lbtr' == t) {
			this.set_type_lbtr();
		} else {
			this.set_type_any();
		}
	}

	this.set_type_ltrb = function() {
		this.p.l = 't';
		this.p.t = 'l';
		this.p.r = 'b';
		this.p.b = 'r';
	}

	this.set_type_lrtb = function() {
		this.p.l = 'r';
		this.p.t = 'b';
		this.p.r = 'l';
		this.p.b = 't';
	}

	this.set_type_lbtr = function() {
		this.p.l = 'b';
		this.p.t = 'r';
		this.p.r = 't';
		this.p.b = 'l';
	}

	this.set_type_any = function() {
		var a = ['lbtr', 'ltrb'];
		if (this.grid.turn > Math.random()) {
			if (this.grid.way > Math.random()) {
				this.set_type_ltrb();
			} else {
				this.set_type_lbtr();
			}
		}
	}

	this.toggle_trace = function(edge) {
		var tf = ! this.t[edge];
		this.trace(edge, tf);
	}

	this.trace = function(edge, tf) {

		if (tf == this.t[edge]) {
			return;
		}

		var a = {l: 'r', t: 'b', r: 'l', b: 't'};

		var tile = this;
		var e = edge;

		// we want to trace the path
		// start with this tile.
		// keep following the path, marking it as traced.
		//
		while (true) {
			tile.t[e] = tf;
			tile.t[tile.p[e]] = tf;
			var n = a[tile.p[e]];
			tile = tile.find_tile(tile.p[e]);
			e = n;
			if (this == tile) {
				if (edge == e) {
					return;
				}
			}
		}
	}

	this.get_type = function() {
		var a = {t: 'ltrb', r: 'lrtb', b: 'lbtr'};
		return a[this.p.l];
	}

	this.get_trace = function() {
		var a = this.get_type().split('');
		var o = '';
		for (var i in a) {
			if (this.t[a[i]]) {
				o += a[i];
			}
		}
		if ('' == o) { o = 'null'; }
		return o;
	}

	this.dump = function() {
		var out = '<img width="64" height="64" border="0" src="';
		out += img;
		var t = this.get_type();
		out += this.get_type() + '-' + this.get_trace() + '-null';
		out += '.gif" />';
		return out;
	}

	this.init();
}

function TangledGrids(grids, rows, cols) {
	this.init = function () {
		this.grids = grids;
		this.rows = rows;
		this.cols = cols;
		this.g = new Array();
		for (var i = 0; i < grids; ++i) { this.new_grid(i); }
	}

	this.new_grid = function(i) {
		this.g[i] = new TangledGrid(this.rows, this.cols);
	}
	this.trace_tile = function(r, c) {
		var i = Math.floor(grids * Math.random());
		if (1/4 > Math.random()) { this.new_grid(i); }
		this.g[i].trace_tile(r, c);
	}

	this.trace_any = function() {
		//this.g[Math.floor(grids * Math.random())].trace_any();
		for (var i = 0; i < grids; ++i) {
			this.g[i].trace_any();
		}
	}

	this.tile_key = function(row, col) {
		var a = new Array();
		for (var i = 0; i < grids; ++i) {
			var tile = this.g[i].find_tile(row, col);
			a[i] = tile.get_trace();
		}
		return a.join('-');
	}

	this.dump_tile = function(row, col) {
		var a = new Array();
		for (var i = 0; i < grids; ++i) {
			var tile = this.g[i].find_tile(row, col);
			a[i] = tile.get_trace();
		}
		var out = '<img width="64" height="64" border="0" src="';
		out += img;
		out += a.join('-');
		out += '.gif" />';
		return out;
	}

	this.dump = function() {
		var out = '';
		out += '<table border="0" cellspacing="0" cellpadding="0">';
		for (var row = 0; row < rows; ++row) {
			out += "<tr>";
			for (var col = 0; col < cols; ++col) {
				out += "<td>";
				out += this.dump_tile(row, col);
				out += "</td>";
			}
			out += "</tr>";
		}
		out += "</table>";
		return out;
	}

	this.init();

}

function TangledGrid(rows, cols) {
	this.grid = new Array();
	this.rows = rows;
	this.cols = cols;
	this.rows = rows;
	this.turn = Math.random();
	this.way = Math.random();
	for (var row = 0; row < rows; ++row) {
		this.grid[row] = new Array();
		for (var col = 0; col < cols; ++col) {
			this.grid[row][col] = new TangledTile(this, row, col);
		}
	}

	this.dump = function() {
		var out = '';
		out += '<table border="0" cellspacing="0" cellpadding="0">';
		for (var row = 0; row < rows; ++row) {
			out += "<tr>";
			for (var col = 0; col < cols; ++col) {
				out += "<td>";
				out += this.find_tile(row, col).dump();
				out += "</td>";
			}
			out += "</tr>";
		}
		out += "</table>";
		return out;
	}

	this.trace_tile = function(r, c) {
		var a = ['l', 't', 'r', 'b'];
		var d = a[Math.floor(Math.random() * 4)];
		var t = this.find_tile(r, c);
		if (.5 > Math.random()) {
			t.change_type();
		}
		t.toggle_trace(d);
	}

	this.trace_any = function() {
		var a = ['l', 't', 'r', 'b'];
		var r = Math.floor(Math.random() * this.rows);
		var c = Math.floor(Math.random() * this.cols);
		var d = a[Math.floor(Math.random() * 4)];
		this.find_tile(r, c).trace(d, true);
	}

	this.find_tile = function(row, col) {
		if (null == row) { return };
		if (null == col) { return };
		var r = row;
		while (r < 0) {r += rows;}
		r %= rows;
		var c = col;
		while (c < 0) {c += cols;}
		c %= cols;

		return this.grid[r][c];
	}
}
